﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Interactivity;
using System.Linq;
using OpenLightGroup.Common.LinqToVisualTree;
using System.Diagnostics;

namespace OpenLightGroup.Common.Behaviors
{
    public class LinqAttachDataContextBehavior : Behavior<FrameworkElement>
    {
        public LinqAttachDataContextBehavior()
        {

        }



        #region Properties

        public string ElementName
        {
            get { return (string)GetValue(ElementNameProperty); }
            set { SetValue(ElementNameProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ElementName.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ElementNameProperty =
            DependencyProperty.Register("ElementName", typeof(string), typeof(AttachDataContextBehavior), new PropertyMetadata(null));




        public object DataContextType
        {
            get { return (object)GetValue(DataContextTypeProperty); }
            set { SetValue(DataContextTypeProperty, value); }
        }

        // Using a DependencyProperty as the backing store for DataContextType.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty DataContextTypeProperty =
            DependencyProperty.Register("DataContextType", typeof(object), typeof(AttachDataContextBehavior), new PropertyMetadata(null));


        #endregion


        protected override void OnAttached()
        {
            base.OnAttached();

            FrameworkElement root = Application.Current.RootVisual as FrameworkElement;

            var matches = from FrameworkElement e in root.Descendants<FrameworkElement>()
                          where e.Name == this.ElementName && e.DataContext.GetType() == this.DataContextType.GetType()
                          select e;

            if (matches != null && matches.Count() == 1)
            {

                this.AssociatedObject.DataContext = matches.First().DataContext;

            }
            else if (matches != null && matches.Count() > 1)
            {

                this.AssociatedObject.DataContext = matches.First().DataContext;

                //Found too many... using first one....                
                Debug.WriteLine("Found too many matches, using the first one....");

            }
            else
            {

                //Nothing found 
                Debug.WriteLine("Could not locate a match.");

            }

            //if (root != null)
            //{

            //    if (root.Name == this.ElementName && root.DataContext != null 
            //        && root.DataContext.GetType() == this.DataContextType.GetType())
            //    {
            //        this.AssociatedObject.DataContext = root.DataContext;
            //    }
            //    else
            //    {

            //        RecursiveSearch(root);

            //    }



            //}

        }

        //private void RecursiveSearch(FrameworkElement parentElement)
        //{
        //    if (this.AssociatedObject.DataContext == null)
        //    {
        //        FrameworkElement currentElement = VisualTreeHelper.GetChild(parentElement, 0) as FrameworkElement;

        //        int childCount = VisualTreeHelper.GetChildrenCount(parentElement);

        //        for (int i = 0; i < childCount; i++)
        //        {
        //            FrameworkElement child = VisualTreeHelper.GetChild(currentElement, i) as FrameworkElement;

        //            var element = child.FindName(this.ElementName) as FrameworkElement;

        //            if (element != null && element.DataContext != null && element.DataContext.GetType() == this.DataContextType.GetType())
        //            {
        //                this.AssociatedObject.DataContext = element.DataContext;
        //                break;
        //            }
        //            else
        //            {
        //                this.RecursiveSearch(child);


        //            }

        //        }

        //    }
        //}

        protected override void OnDetaching()
        {
            base.OnDetaching();

            // Insert code that you would want run when the Behavior is removed from an object.
        }


    }
}